package transfer;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;

public class FileTransferConnection {

	private static final int TRANSFER_PORT = 17171;

	private ServerSocket serverSocket;
	private String ip = null;

	private static FileTransferConnection instance = null;
	private Socket socket = null;

	private ObjectInputStream inputObject = null;
	ObjectOutputStream outputObject = null;

	public static FileTransferConnection getInstance() {
		if (null == instance) {
			instance = new FileTransferConnection();
		}
		return instance;
	}

	public void connect(boolean isHost, String ip)
			throws FileTransferConnectionException {

		try {
			if (isHost) {
				serverSocket = new ServerSocket(TRANSFER_PORT);
				System.out.println("Server is up");
			} else {
				this.ip = ip;

			}
		} catch (IOException e) {
			throw new FileTransferConnectionException(e);
		}

	}

	public boolean sendFile(File file) throws FileTransferConnectionException {

		try {
			socket = serverSocket.accept();
			System.out.println("Accepted connection : " + socket);

			outputObject = new ObjectOutputStream(socket.getOutputStream());
			outputObject.writeObject(file);

			OutputStream out = socket.getOutputStream();

			// sendfile
			FileInputStream in = new FileInputStream(file);

			System.out.println("Sending file: " + file.getName() + "...");

			byte[] mb = new byte[1024];
			for (int c = in.read(mb); c > -1; c = in.read(mb)) {
				out.write(mb, 0, c);

			}
			socket.close();
			System.out.println("file: " + file.getName()
					+ " was sent successfully");
			return true;
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			System.out.println("Sending file: " + file.getName()
					+ " failed, will try again");
		}
		return false;

	}

	public File getFile() throws FileTransferConnectionException {

		// localhost for testing
		socket = null;
		File file = null;

		System.out.println("Connecting...");
		while (socket == null) {
			try {
				socket = new Socket(ip, TRANSFER_PORT);
			} catch (IOException e) {
				System.out
						.println("Server is down, waiting 10 sec before trying again...");
				try {
					Thread.sleep(10000);
				} catch (InterruptedException e1) {
					// TODO Auto-generated catch block
					System.out.println("yoyo4");
					e1.printStackTrace();
				}
			}
		}

		try {
			inputObject = new ObjectInputStream(socket.getInputStream());
			file = (File) inputObject.readObject();
			while (null == file)
				;

			System.out.println("Downloading file: " + file.getName());
			// receive file
			InputStream in = socket.getInputStream();
			FileOutputStream out = null;

			out = new FileOutputStream(Transfer.TO_LOG_FOLDER + file.getName());

			byte[] mb = new byte[1024];
			for (int c = in.read(mb, 0, 1024); c > 0; c = in.read(mb, 0, 1024)) {
				out.write(mb, 0, c);
			}
			// for(int c = in.read(); c!= -1; c = in.read()){ out.write(c);
			// }
			out.close();
			socket.close();

			return file;
		} catch (FileNotFoundException e2) {
			// TODO Auto-generated catch block
			System.out.println("yoyo5");
			e2.printStackTrace();
		} catch (UnknownHostException e3) {
			// TODO Auto-generated catch block
			System.out.println("yoyo1");
			e3.printStackTrace();
		} catch (IOException e3) {
			// TODO Auto-generated catch block
			System.out.println("Server went down");
			// e3.printStackTrace();
		} catch (ClassNotFoundException e) {
			System.out.println("yoyo3");
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		if (file != null)
			System.out.println("Downloading file: " + file.getName() + " failed");
		return null;
	}

}
